#!/usr/bin/env python

import time, random, string


class Session ( object ):
	def __init__ ( self, backend, sess_id = None, sess_data = None ):
		super ( Session, self ).__init__()

		self._backend = backend
		
		if sess_data: self._sess_data = sess_data
		else: self._sess_data = {}
		
		if sess_id: self._sess_id = sess_id
		else: self._sess_id = self._new_sess_id()


	def set ( self, key, val ):
		self._sess_data[key] = val


	def get ( self, key, def_val = None ):
		return self._sess_data.get ( key, def_val )

	
	def save ( self ):
		self._backend.save_session ( self._sess_id, self._sess_data )


	def get_id ( self ):
		return self._sess_id


	def _new_sess_id ( self ):
		t = "%08x" % int(time.time())
		unique = "%04x" % (self._backend.get_unique_id() % 0xFFFF)
		
		rnd = random.sample(string.digits + string.ascii_lowercase, 20)
		rnd = ''.join(rnd)
		return ( unique + rnd[:2] + t[0] + rnd[2:4] + t[1] + rnd[4:6] + t[2] +
			rnd[6:8] + t[3] + rnd[8:10] + t[4] + rnd[12:14] +
			t[5] + rnd[14:16] + t[6] + rnd[18] + t[7] )


class SessionManager ( object ):
	def __init__ ( self, backend = 'db', *args, **kwargs ):
		module = 'sessman_' + backend
		os3 =  __import__ ( 'os3.session.' + module )
		mod = getattr ( os3.session, module )
		self._backend = mod.SessionManagerBackend ( *args, **kwargs )


	def new ( self, sess_id = None ):
		if sess_id:
			#try to load a saved session
			sess = self.load ( sess_id )
			if sess: return sess
		sess = Session ( self._backend, sess_id )
		self._backend.add_session ( sess.get_id() )
		return sess


	def load ( self, sess_id ):
		sess = self._backend.get_session ( sess_id )
		if not sess: return None
		sess_data, sess_mod_date = sess
		return Session ( self._backend, sess_id, sess_data )


	def delete ( self, sess_id ):
		self._backend.del_session ( sess_id )

	
	def delete_old ( self, time_limit ):
		self._backend.del_old_sessions ( time_limit )


	def list ( self ):
		return self._backend.list_sessions()

	
	def install ( self ):
		self._backend.install()


	def drop ( self ):
		self._backend.drop()


	def check ( self ):
		self._backend.check()


